package com.feemanage.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cfg.domain.ClaimProjectShow;
import com.cfg.mapper.ClaimProjectShowMapper;
import com.common.core.domain.entity.SysUser;
import com.common.core.page.PageDomain;
import com.common.utils.CurrentRoleUtils;
import com.common.utils.SecurityUtils;
import com.common.utils.sql.SqlUtil;
import com.feemanage.common.SearchUtils;
import com.feemanage.domain.*;
import com.feemanage.domain.bo.BizProjectBudgetFeeBo;
import com.feemanage.domain.bo.FundsFeeShowBo;
import com.feemanage.domain.vo.*;
import com.feemanage.mapper.*;
import com.feemanage.service.IcWIncomeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class cWIncomeServiceImpl implements IcWIncomeService {

    @Autowired
    private cWIncomeMapper baseMapper;

    @Autowired
    private cWIncomeClaimMapper claimMapper;

    @Autowired
    private bizBudgetAlterationMapper alterationMapper;

    @Autowired
    private ClaimProjectShowMapper projectShowMapper;

    @Autowired
    private bizProjectIncomeMapper incomeMapper;

    @Autowired
    private bizProjectFeeCardMapper feeCardMapper;

    @Autowired
    private bizClaimManageMapper manageMapper;

    @Autowired
    private bizManageFeeMapper manageFeeMapper ;

    @Autowired
    private  bizClaimFeeCardBudgetMapper budgetMapper;

    @Autowired
    private  bizClaimProjectIncomeMapper claimProjectIncomeMapper;

    private final static String project_Class_zX="zXProject"; // 纵向项目

    private final static String project_Class_yF="yfContract"; // 横向项目
    private final static String feeSchemeId = "2c97a35494de0ad60194fdf648120436"; //纵向项目-默认管理费方案

    private final static String budgetSplitModde = "chargerConfirm" ;//额度拆分方式--默认负责人拆分

    private final static String budgetSplitModde_lx = "liuxiaoBudgetSplit" ;//额度拆分方式--拆分总留校额度

    private final static String budgettype_lx = "liuxiao" ;//留校
    private final static String budgettype_yf = "yfContract" ;//横向的预算类型


    /**
     * 查询银行到款列表
     * @param pageDomain
     * @param cwIncome
     * @return
     */
    @Override
    public IPage<BizCwIncomeVo> selectList(PageDomain pageDomain, BizCwIncome cwIncome) {
        Page<BizCwIncomeVo> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
        QueryWrapper<BizCwIncome> wrapper = getQuery(cwIncome);
        //当前用户的角色
        String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
        if (("biz_kyry").equals(currentRoleKey)) {//科研人员
            if(StringUtils.isEmpty(cwIncome.getNote())){
                IPage<BizCwIncomeVo> list = new Page<>();
                list.setRecords(new ArrayList<>());
                list.setTotal(0);
                return list;
            }
        }
        if (("biz_kyms").equals(currentRoleKey)) {//科研秘书
            wrapper.in("c.fee_status",Arrays.asList(1, 2));
        }
        wrapper.groupBy("c.id,c.cw_dch,c.income_unit,c.note,c.fee_status,c.fee_value,c.income_type,c.income_date");
        String orderByColumn = SqlUtil.escapeOrderBySql(pageDomain.getOrderByColumn());
        boolean isASC = SqlUtil.escapeOrderBySql(pageDomain.getIsAsc()).equalsIgnoreCase("asc");
        if (!StringUtils.isEmpty(orderByColumn))
        {
            wrapper.orderBy(true,isASC,orderByColumn);
        }
        return baseMapper.selectListPage(page,wrapper);
    }

    /**
     * 导出
     * @param cwIncome
     * @return
     */
    @Override
    public List<BizCwIncomeVo> selectExportList(PageDomain pageDomain,BizCwIncome cwIncome) {
        QueryWrapper<BizCwIncome> wrapper = getQuery(cwIncome);
        wrapper.groupBy("c.id,c.cw_dch,c.income_unit,c.note,c.fee_status,c.fee_value,c.income_type,c.income_date");
        String orderByColumn = SqlUtil.escapeOrderBySql(pageDomain.getOrderByColumn());
        boolean isASC = SqlUtil.escapeOrderBySql(pageDomain.getIsAsc()).equalsIgnoreCase("asc");
        if (!StringUtils.isEmpty(orderByColumn))
        {
            wrapper.orderBy(true,isASC,orderByColumn);
        }
        return baseMapper.selectListPage(wrapper);
    }


    /**
     * 查询详细信息
     * @param cwIncome
     * @return
     */
    @Override
    public BizCwIncomeVo selectOne(BizCwIncome cwIncome){
        QueryWrapper<BizCwIncome> wrapper = getQuery(cwIncome);
        return baseMapper.selectListOne(wrapper);
    }

    /**
     * 拼接检索条件
     * @param cwIncome
     * @return
     */
    private QueryWrapper<BizCwIncome> getQuery(BizCwIncome cwIncome) {
        Map<String, Object> params = cwIncome.getParams();
        QueryWrapper<BizCwIncome> wrapper = Wrappers.query();
        wrapper.eq(StringUtils.isNotBlank(cwIncome.getId()), "c.id", cwIncome.getId())
                .like(StringUtils.isNotBlank(cwIncome.getCwDch()), "c.cw_dch", cwIncome.getCwDch())
                .like(StringUtils.isNotBlank(cwIncome.getIncomeUnit()), "c.income_unit", cwIncome.getIncomeUnit())
                .like(StringUtils.isNotBlank(cwIncome.getNote()), "c.note", cwIncome.getNote())
                .between(ObjectUtil.isNotEmpty(params.get("beginTime")) && ObjectUtil.isNotEmpty(params.get("endTime")),
                        "c.income_date", params.get("beginTime"), params.get("endTime"))
                .ge(ObjectUtil.isNotEmpty(params.get("beginTime"))  && ObjectUtil.isEmpty(params.get("endTime")),"c.income_date", params.get("beginTime"))
                .le(ObjectUtil.isEmpty(params.get("beginTime"))&& ObjectUtil.isNotEmpty(params.get("endTime")) ,"c.income_date", params.get("endTime"))
                .between(ObjectUtil.isNotEmpty(params.get("maxfee")) && ObjectUtil.isNotEmpty(params.get("minfee")),
                        "c.fee_value", SearchUtils.processAmount(params.get("minfee")), SearchUtils.processAmount(params.get("maxfee")))
                .ge(ObjectUtil.isNotEmpty(params.get("minfee")) && ObjectUtil.isEmpty(params.get("maxfee")),"c.fee_value", SearchUtils.processAmount(params.get("minfee")))
                .le(ObjectUtil.isNotEmpty(params.get("maxfee")) && ObjectUtil.isEmpty(params.get("minfee")),"c.fee_value", SearchUtils.processAmount(params.get("maxfee")))
                .eq(StringUtils.isNotBlank(cwIncome.getIncomeType()), "c.income_type", cwIncome.getIncomeType())
                .eq(StringUtils.isNotBlank(cwIncome.getFeeStatus()), "c.fee_status", cwIncome.getFeeStatus());
        return wrapper;
    }

    /**
     * 新增
     * @param cwIncome
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean addCwIncome(BizCwIncome cwIncome) {
        return baseMapper.insert(cwIncome) >0;
    }

    /**
     * 编辑
     * @param cwIncome
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean editCwIncome(BizCwIncome cwIncome) {
        return baseMapper.updateById(cwIncome) >0;
    }

    /**
     * 删除
     * @param ids
     * @param isValid
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean delCwIncome(Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }

        return baseMapper.deleteBatchIds(ids) >0;
    }


    /**
     * 检查项目是否满足认领要求
     * @param projectId
     * @return
     */
    @Override
    public String checkProject(String projectId) {

        QueryWrapper<BizCwIncomeClaim> wrapper = new QueryWrapper<BizCwIncomeClaim>()
                .eq("PROJECT_ID", projectId)
                .in("CHECKSTATUS", -1,0,1,3);
        if(claimMapper.selectCount(wrapper) >0){
            return "cwIncomeClaim";  //当前项目有未结束的认领经费，不能进行经费认领！
        };
        QueryWrapper<BizBudgetAlteration> alterationwrapper = new QueryWrapper<BizBudgetAlteration>()
                .eq("PROJECT_ID", projectId)
                .in("CHECKSTATUS", -1,0,1,3);
        if(alterationMapper.selectCount(alterationwrapper) >0){
            return "alteration";  //当前项目有未结束的调账经费，不能进行经费认领！
        }

        //判断退回的规则暂不明确，后续添加
        if(false){
            return  "claimBack" ;//当前项目有未结束的退回经费，不能进行经费认领！
        }
        String type = budgettype_lx;
        ClaimProjectShow  projectShow =projectShowMapper.selectClaimProjectOne(new QueryWrapper<ClaimProjectShow>().eq("VP.ID", projectId));
        if(ObjectUtils.isNotEmpty(projectShow) && projectShow.getProjectClass().equalsIgnoreCase("yfContract")){
            type = budgettype_yf;
        }

        Long count = claimMapper.selectbudgetCount(new QueryWrapper<BizProjectBudgetFeeBo>()
                .eq("PROJECT_ID", projectId).eq("BUDGET_TYPE",type));

        if (count<=0){
            return "noProBudget"; //当前项目没有登记预算，请补充预算后再经费认领！
        }


        Long incomecount = incomeMapper.selectCount(new QueryWrapper<BizProjectIncome>()
                .eq("PROJECT_ID", projectId));
        if(incomecount <=0){
            return "noIncome";  //该项目没有到账信息,无法进行调账!
        };

        return "";
    }

    /**
     * 获取项目列表
     * @param pageDomain
     * @param show
     * @return
     */
    @Override
    public IPage<ClaimProjectShow> selectVproject(PageDomain pageDomain, ClaimProjectShow show){
        Page<ClaimProjectShow> page = new Page<>(pageDomain.getPageNum(), pageDomain.getPageSize());
        QueryWrapper<ClaimProjectShow> wrapper = Wrappers.query();
        wrapper.eq(StringUtils.isNotEmpty(show.getProjectId()),"vp.id",show.getProjectId())
                .like(StringUtils.isNotBlank(show.getProjectClass()),"vp.project_class",show.getProjectClass());
         if(StringUtils.isNotBlank(show.getName())){
            wrapper.and((wrappers) -> {
                        wrappers.like("vp.name",show.getName())
                        .or().like("vp.code",show.getName())
                        .or().like("vp.charger_name",show.getName())
                        .or().like("su.account",show.getName());;
                    });
         }

        if (StringUtils.isEmpty(show.getProjectId())){
            //当前用户的角色
            String currentRoleKey = CurrentRoleUtils.getCurrentRoleKey();
            SysUser loginUser = SecurityUtils.getLoginUser().getUser();
            if (("biz_kyry").equals(currentRoleKey)) {//科研人员
                wrapper.eq(ObjectUtil.isNotEmpty(loginUser.getUserRealId()),"vp.charger_code",loginUser.getUserRealId());
            }
            if (("biz_kyms").equals(currentRoleKey)) {//科研秘书
                String units = loginUser.getUnitAdminScopeReal();
                if (StringUtils.isNotEmpty(units)) {
                    List<String> unit = Arrays.stream(units.split(",")).collect(Collectors.toList());
                    wrapper.in("vp.unit_id",unit);
                }
            }
        }
        //项目审核状态为审核并通过，认领时增加条件：项目状态为进行中才能认领
        wrapper.eq("vp.checkStatus",2)
                .eq(StringUtils.isNotEmpty(show.getProjectStatusId()),"vp.PROJECT_STATUS_ID",show.getProjectStatusId());
        IPage<ClaimProjectShow> list;
        if(StringUtils.equals(show.getType(),"outbound")){
            list = projectShowMapper.selectOutboundProjectList(page,wrapper);
        }else{
            list =projectShowMapper.selectClaimProjectList(page,wrapper);
        }
        return list;
    }

    /**
     * 获取认领和项目相关的数据--projectId，claimId，cwIncomeId
     * @param showBo
     * @return
     */
    @Override
    public ClaimFeeShowVo selectClaimFeeInfo(FundsFeeShowBo showBo){
        ClaimFeeShowVo show = new ClaimFeeShowVo();
        ClaimProjectShow projectShow = projectShowMapper.selectClaimProjectOne(new QueryWrapper<ClaimProjectShow>()
                .eq("vp.id",showBo.getProjectId()).last(" limit 1"));
        BizCwIncomeVo cwIncome = baseMapper.selectListOne(new QueryWrapper<BizCwIncome>()
                .eq("c.id",showBo.getCwIncomeId()));
        BizProjectIncome claim = incomeMapper.selectOne(new QueryWrapper<BizProjectIncome>()
                .select(" sum(income_fee) as income_fee,SUM(outbound_fee) as outbound_fee")
                .eq("project_id",showBo.getProjectId()));
        BizCwIncomeClaim incomeClaim = claimMapper.selectOne(new QueryWrapper<BizCwIncomeClaim>().eq("PROJECT_ID",showBo.getProjectId()).eq(StringUtils.isNotEmpty(showBo.getClaimId()),"ID",showBo.getClaimId())
                .last(" limit 1 "));
        BigDecimal divisor = new BigDecimal("10000");
        BigDecimal cwnotincomeFee = BigDecimal.valueOf(0); //财务可领金额
        BigDecimal incomeFee = BigDecimal.valueOf(0) ;//项目已认领
        BigDecimal outboundFee =BigDecimal.valueOf(0) ; //项目累计外拨
        if(ObjectUtil.isNotNull(cwIncome)){
            cwnotincomeFee = ObjectUtil.isNotNull(cwIncome.getNotClaimfee())?cwIncome.getNotClaimfee():cwnotincomeFee;

        }
        if(ObjectUtil.isNotNull(claim)){
            incomeFee = ObjectUtil.isNotNull(claim.getIncomeFee())?claim.getIncomeFee():incomeFee;
            outboundFee = ObjectUtil.isNotNull(claim.getOutboundFee())?claim.getOutboundFee():outboundFee;
        }

        BigDecimal FeeAuthorize = ObjectUtil.isNotNull(projectShow.getFeeAuthorize())?projectShow.getFeeAuthorize(): BigDecimal.valueOf(0) ;
        BigDecimal OutFee = ObjectUtil.isNotNull(projectShow.getOutFee())?projectShow.getOutFee(): BigDecimal.valueOf(0) ;
        String projectfeeInfo = FeeAuthorize.divide(divisor,6, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString() +"万元";
        String incomeFeeString = incomeFee.divide(divisor, 6, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
        if(projectShow.getProjectClass().equals(project_Class_zX)){
            projectfeeInfo += "(已入账"+ incomeFeeString+"万元。其中计划外拨 "+OutFee.divide(divisor,2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString() +"万元，已外拨"+outboundFee.divide(divisor, 2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString()+"万元)";
        }else{
            projectfeeInfo +="(已入账"+ incomeFeeString +"万元)";
        }
        //财务可认领金额和项目未到账金额取min =可认领金额
        BigDecimal canClaimFee = cwnotincomeFee.min(FeeAuthorize.subtract(incomeFee));
        show.setProjectClass(projectShow.getProjectClass());//项目类型
        show.setIncomeFee(incomeFee);//项目已认领金额
        show.setProjectId(projectShow.getProjectId());//项目id
        show.setProjectName(projectShow.getName());//项目名称
        show.setProjectClass(projectShow.getProjectClass());//项目类型
        show.setChargerId(projectShow.getChargerCode());//负责人id
        show.setChargerName(projectShow.getChargerName());//负责人名称
        show.setPlanOutboundFee(OutFee);//计划外拨金额
        show.setProjectFeeInfo(projectfeeInfo);//项目合同金额展示信息
        show.setCanClaimFee(canClaimFee); //可认领金额
        show.setOutboundFee(outboundFee);//已外拨金额;
        show.setClaimFeeInfo("可认领"+canClaimFee.divide(divisor, 6, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString()+"万元"); //可认领费用提示信息
        show.setNotIncomeFee(FeeAuthorize.subtract(incomeFee));//项目未到账金额=合同金额-到账金额
        show.setBudgetSplitModde(ObjectUtil.isNotNull(incomeClaim)?incomeClaim.getBudgetSplitModde():budgetSplitModde); //获取拆分方式
        List<ClaimIncomeFeeVo> incomeFeeVos = new ArrayList<>();
        if (StringUtils.isEmpty(showBo.getClaimId())){

            show.setFeeSchemeId(feeSchemeId); //默认取管理费
            //获取初始化经费卡
            showBo.setChargerId(projectShow.getChargerCode());
            ClaimIncomeFeeVo incomeFeeVo = new ClaimIncomeFeeVo();
            String feecard = selectIncomeFee(showBo.getProjectId(),showBo.getChargerId());
            incomeFeeVo.setFeeCardNum(feecard);//获取卡号
            show.setHasCardLiuxiaoBudget(StringUtils.isNotBlank(feecard)); //是否有卡号
            incomeFeeVo.setFeeChargerId(projectShow.getChargerCode()); //经费卡号负责人id
            incomeFeeVo.setFeeChargerName(projectShow.getChargerName());//经费卡负责人名称
            incomeFeeVo.setFeeChargerCode(projectShow.getAccount());//经费负责人工号
            incomeFeeVo.setUnitId(projectShow.getUnitId());//所属单位id
            incomeFeeVo.setFeeChargerUnitName(projectShow.getUnitName());//所属单位名称
            incomeFeeVo.setOutboundFee(BigDecimal.valueOf(0));//外拨
            incomeFeeVo.setSchoolFee(BigDecimal.valueOf(0));//留校
            incomeFeeVos.add(incomeFeeVo);

        }else{
            //从表中取值
            show.setFeeSchemeId(incomeClaim.getFeeSchemeId());
            List<BizClaimProjectIncome> incomeList = claimProjectIncomeMapper.selectList(new LambdaQueryWrapper<BizClaimProjectIncome>()
                    .eq(BizClaimProjectIncome::getCwIncomeClaimId,showBo.getClaimId())
                    .eq(BizClaimProjectIncome::getProjectId,showBo.getProjectId()));
            for (BizClaimProjectIncome income : incomeList){
                ClaimIncomeFeeVo incomeFeeVo = new ClaimIncomeFeeVo();
                BeanUtils.copyProperties(income,incomeFeeVo);
                incomeFeeVos.add(incomeFeeVo);
            }
        }
        show.setClaimIncomeFeeShow(incomeFeeVos);
        return  show;
    }


    /**
     * 初始化认领经费卡到账信息--projectId,chargerId
     * @param proid,chargerid
     * @return
     */
    public String selectIncomeFee(String proid, String chargerid){

        BizProjectFeeCard feeCard = feeCardMapper.selectOne(new QueryWrapper<BizProjectFeeCard>()
                .eq("project_id",proid)
                .eq("fee_charger_id",chargerid)
                .orderByDesc("createdate ")
                .last(" limit 1 "));

        if (ObjectUtil.isNotNull(feeCard)) {
             return  feeCard.getFeeCardNum();//经费卡号
        }
        return  null;
    }

    /**
     * 管理费
     * @param showBo
     * @return
     */
    @Override
    public List<ClaimManageFeeVo> selectManageFee(FundsFeeShowBo showBo){

        List<ClaimManageFeeVo> manageFeeVo = manageMapper.selectManageFeeSubjectList(new QueryWrapper<ClaimManageFeeVo>().eq("bfs.feeschemeid",feeSchemeId));

        List<BizManageFee> manageFeeList = manageFeeMapper.selectList(new QueryWrapper<BizManageFee>().select(" sum(subject_fee) as subject_fee,subject_code")
                .eq("project_id", showBo.getProjectId())
                .ne(StringUtils.isNotEmpty(showBo.getCwIncomeId()), "claim_id", showBo.getCwIncomeId())
                .groupBy("subject_code"));
        List<BizClaimManageFee> claimManageFeeList = new ArrayList<>();
        if(StringUtils.isNotEmpty(showBo.getClaimId())) {
            claimManageFeeList = manageMapper.selectList(new QueryWrapper<BizClaimManageFee>()
                    .eq("project_id", showBo.getProjectId()).eq("claim_id",showBo.getClaimId()));
        }

        for(ClaimManageFeeVo claimManageFee: manageFeeVo) {
            ClaimSubManageFeeVo subManageFeeVos = new ClaimSubManageFeeVo();
            //编辑，查看，BizClaimManageFee表中的值
            if(StringUtils.isNotEmpty(showBo.getClaimId()) && !claimManageFeeList.isEmpty()){
               BizClaimManageFee mangeFee = claimManageFeeList.stream().filter(t->t.getSubjectCode().equals(claimManageFee.getSubjectCode())).findFirst().orElse(null);
                    if (mangeFee != null && ObjectUtil.isNotEmpty(mangeFee)){
                        subManageFeeVos.setId(mangeFee.getId());
                        subManageFeeVos.setFeeChargerId(mangeFee.getFeeChargerId());
                        subManageFeeVos.setComputeWay(mangeFee.getComputeWay());
                        subManageFeeVos.setSubjectFee(ObjectUtils.isNotEmpty(mangeFee.getSubjectFee())?mangeFee.getSubjectFee():BigDecimal.ZERO);
                        subManageFeeVos.setSplitManageFee(ObjectUtils.isNotEmpty(mangeFee.getSplitManageFee())?mangeFee.getSplitManageFee():BigDecimal.ZERO);
                    }
               }else{
                //新增时，计算总的值应该取biz_manage_fee表中的数据
                BigDecimal manageFee = BigDecimal.valueOf(0);
                if(manageFeeList != null && !manageFeeList.isEmpty()){
                    manageFee = manageFeeList.stream().filter(t->t.getSubjectCode().equals(claimManageFee.getSubjectCode())).map(BizManageFee::getSubjectFee).findFirst().orElse(BigDecimal.valueOf(0));
                }
                subManageFeeVos.setSplitManageFee(manageFee);
            }
            List<ClaimSubManageFeeVo> list = new ArrayList<>();
            list.add(subManageFeeVos);
            claimManageFee.setClaimSubManageFee(list);
        }

        return manageFeeVo;
    }


    /**
     * 额度拆分费用显示-projectid，changeid(所有经费卡负责人)，budgetSplitModde
     * @param showBo
     * @return
     */
    @Override
    public List<ClaimBudgetFeeShowVo> seletcBudegtFee(FundsFeeShowBo showBo) {

        String budgettype = budgettype_lx;
        if (showBo.getProjectClass().equals(project_Class_yF)) {
            budgettype = budgettype_yf;
        }

        List<ClaimBudgetFeeShowVo> list = budgetMapper.selectFeeCardBudgetList(new QueryWrapper<ClaimBudgetFeeShowVo>()
                .eq("bpbf.project_id", showBo.getProjectId())
                .eq("bpbf.BUDGET_TYPE", budgettype));
        List<BizClaimFeeCardBudget> cardBudget= new ArrayList<>();
        List<BizClaimFeeCardBudget> cardBudget1=new ArrayList<>();
        if (!showBo.getBudgetSplitModde().equals(budgetSplitModde_lx)) {
            cardBudget = budgetMapper.selectList(new QueryWrapper<BizClaimFeeCardBudget>()
                    .select("SUBJECT_ID,FEE_CHARGER_ID,SUM(SUBJECT_FEE) AS SUBJECT_FEE")
                    .eq("project_id", showBo.getProjectId())
                    .ne(StringUtils.isNotEmpty(showBo.getClaimId()), "claim_id", showBo.getClaimId())
                    .groupBy("FEE_CHARGER_ID ,SUBJECT_ID"));
            if(StringUtils.isNotEmpty(showBo.getClaimId())){
                cardBudget1 = budgetMapper.selectList(new QueryWrapper<BizClaimFeeCardBudget>()
                        .eq("project_id", showBo.getProjectId())
                        .eq("CLAIM_ID", showBo.getClaimId()));
            }
        }

        for(ClaimBudgetFeeShowVo budgetfee: list){
            List<ClaimSubBudgetFeeShowVo> subBudgetFeeShowVoList = new ArrayList<>();
            for(String personid:  Arrays.asList(showBo.getPersonIds())){
                ClaimSubBudgetFeeShowVo  subBudgetFeeShowVo = new ClaimSubBudgetFeeShowVo();
                BigDecimal splitfee = BigDecimal.valueOf(0);
                BigDecimal budegtfee = BigDecimal.valueOf(0);
                //拆分总留校额度,不分割
                if (showBo.getBudgetSplitModde().equals(budgetSplitModde_lx)) {
                    //原本业务逻辑: 当前人是项目负责人，展示总额度，其他人，展示0，页面上可填写
                    //由于目前业务，是给项目负责人建卡，所以只展示一个
                    budegtfee = budgetfee.getSubjectFee();
                }else {
                    if(cardBudget != null && !cardBudget.isEmpty()){
                        splitfee = cardBudget.stream().filter(s->s.getSubjectId().equals(budgetfee.getSubjectId()))
                                .filter(s->s.getFeeChargerId().equals(personid)).map(BizClaimFeeCardBudget::getSubjectFee).findFirst().orElse(BigDecimal.valueOf(0));
                    }
                    if(StringUtils.isNotEmpty(showBo.getClaimId()) && !cardBudget1.isEmpty()){
                        budegtfee = cardBudget1.stream().filter(s->s.getSubjectId().equals(budgetfee.getSubjectId()))
                                .filter(s->s.getFeeChargerId().equals(personid)).map(BizClaimFeeCardBudget::getSubjectFee).findFirst().orElse(BigDecimal.valueOf(0));
                    }
                }
                subBudgetFeeShowVo.setPersonId(personid);
                subBudgetFeeShowVo.setSplitBudgetFee(splitfee); //写入合计
                subBudgetFeeShowVo.setBudgetFee(budegtfee);//额度
                subBudgetFeeShowVoList.add(subBudgetFeeShowVo);
            }
            budgetfee.setClaimSubBudgetFeeShow(subBudgetFeeShowVoList);
        }
        
        if(showBo.getBudgetSplitModde().equals(budgetSplitModde_lx)){
            ClaimProjectShow projectShow = projectShowMapper.selectClaimProjectOne(new QueryWrapper<ClaimProjectShow>()
                    .eq("vp.id",showBo.getProjectId()).last(" limit 1")); //计算外拨费

            ClaimBudgetFeeShowVo outboundfee = new ClaimBudgetFeeShowVo();
            outboundfee.setSubjectCode("outboundCode");//转拨费
            outboundfee.setSubjectId("outboundCode");
            outboundfee.setSubjectName("转拨费");
            outboundfee.setHasChildren("0");
            outboundfee.setSubjectLevel(0);
            outboundfee.setSubjectFee(projectShow.getOutFee());//外拨费
            List<ClaimSubBudgetFeeShowVo> list1 = new ArrayList<>();
            ClaimSubBudgetFeeShowVo  subBudgetFeeShowVo = new ClaimSubBudgetFeeShowVo();
            subBudgetFeeShowVo.setPersonId(showBo.getPersonIds()[0]);
            subBudgetFeeShowVo.setBudgetFee(projectShow.getOutFee());
            subBudgetFeeShowVo.setSplitBudgetFee(BigDecimal.valueOf(0));
            list1.add(subBudgetFeeShowVo);
            outboundfee.setClaimSubBudgetFeeShow(list1);
            list.add(outboundfee);
        }

        ClaimBudgetFeeShowVo  total = new ClaimBudgetFeeShowVo();
        total.setHasChildren("0");
        total.setSubjectName("合计");
        BigDecimal sum = list.stream()
                .filter(s->s.getHasChildren().equalsIgnoreCase("0"))
                .map(ClaimBudgetFeeShowVo::getSubjectFee).reduce(BigDecimal.ZERO,BigDecimal::add);
        total.setSubjectFee(sum);
        List<ClaimSubBudgetFeeShowVo> totallist = new ArrayList<>();
        for (String personid:  Arrays.asList(showBo.getPersonIds())){
            ClaimSubBudgetFeeShowVo totalfee = new ClaimSubBudgetFeeShowVo();//合计
            totalfee.setPersonId(personid);
            BigDecimal sum1 = list.stream()
                    .filter(s->s.getHasChildren().equalsIgnoreCase("0"))
                    .map(s->s.getClaimSubBudgetFeeShow().stream().filter(item -> item.getPersonId().equals(personid))
                            .map(ClaimSubBudgetFeeShowVo::getBudgetFee).reduce(BigDecimal.ZERO,BigDecimal::add))
                    .reduce(BigDecimal.ZERO,BigDecimal::add);

            totalfee.setBudgetFee(sum1);
            BigDecimal sum2 = list.stream()
                    .filter(s->s.getHasChildren().equalsIgnoreCase("0"))
                    .map(s->s.getClaimSubBudgetFeeShow().stream().filter(item -> item.getPersonId().equals(personid))
                            .map(ClaimSubBudgetFeeShowVo::getSplitBudgetFee).reduce(BigDecimal.ZERO,BigDecimal::add))
                    .reduce(BigDecimal.ZERO,BigDecimal::add);
            totalfee.setSplitBudgetFee(sum2);
            totallist.add(totalfee);
            total.setClaimSubBudgetFeeShow(totallist);
        }

        list.add(0,total); //在最前面增加一行

        return list;
    }
}
